/*******************************************************************************
* Project: QSAR(Cute Software Architecture) 
*
* Copyright: Copyright(C) 2024 by YuetingBen, All Rights Reserved
*
* File name: Dem.c
*
* Brief: ;
*
* Author: Yueting.Ben
*
* Module: Dem
*
*******************************************************************************/

/** HEADER FILES **/
#include "Dem.h"


/** MACRO DEFINITION **/
#define DTCExtendedDataRecordNumber_0xFF 0xFF
#define DTCSnapshotRecordNumber_0xFF 0xFF


/** TYPEDEF DEFINITION **/
typedef uint16 Dem_GroupIdType;
#define DEM_GROUPID_INVAILD ((Dem_GroupIdType)0xFF)
#define DEM_GROUPID_Max ((Dem_GroupIdType)0u)
#define DEM_GROUPID_ALL (DEM_GROUPID_Max)



typedef struct
{
    Dem_MonitorStatusType monitorStatus;
    Dem_UdsStatusByteType udsStatus;
    Dem_EventStatusType eventStatusOld;
    sint8 faultDetCounter;
    Dem_DtcNvmDataType* DtcNvmDataPtr;
}Dem_DtcInfoType;

typedef struct
{
    Dem_DtcInfoType* DtcInfoRef;
    Dem_EventIdType SelectedEventId;
    Dem_GroupIdType SelectedGroupId;
    Dem_UdsStatusByteType StatusMask;
    uint8 SelectedExtendedDataNumber;
    uint8 ExtendedDataNumberIndex;
    uint8 SelectedSnapshotRecordNumber;
    uint8 SnapshotRecordNumberIndex;
    uint8 DtcDisableFlag;
}Dem_DemInfoType;


/** LOCAL DATA DECLARATION **/
static Dem_DtcInfoType Dem_DtcInfo[DemConf_DemEventId_Max];
static Dem_DemInfoType Dem_DemInfo[DemConf_DemClientId_Max];

/** GLOBAL DATA DECLARATION **/


/** LOCAL FUNCTION DECLARATION **/
static Std_ReturnType Dem_LookupNvmIndex(
    Dem_EventIdType EventId,
    uint8* nvmIndex
);

static Std_ReturnType Dem_LookupDTCGroupId(
    uint32 DTC,
    Dem_EventIdType* GroupId
);

static Std_ReturnType Dem_LookupDTCEventId(
    uint32 DTC,
    Dem_EventIdType* EventId
);


/** GLOBAL FUNCTION DECLARATION **/
void Dem_GetVersionInfo(
    Std_VersionInfoType* versionInfo
);

void Dem_Init(
    const Dem_ConfigType* ConfigPtr
);

Std_ReturnType Dem_ClearDTC(
    uint8 ClientId
);

Std_ReturnType Dem_SetEventStatus(
    Dem_EventIdType EventId,
    Dem_EventStatusType EventStatus
);

Std_ReturnType Dem_SetEventStatusWithMonitorData(
    Dem_EventIdType EventId,
    Dem_EventStatusType EventStatus,
    Dem_MonitorDataType monitorData0,
    Dem_MonitorDataType monitorData1
);

Std_ReturnType Dem_GetDTCStatusAvailabilityMask(
    uint8 ClientId,
    Dem_UdsStatusByteType* DTCStatusMask,
    Dem_DTCOriginType DTCOrigin
);

Std_ReturnType Dem_GetStatusOfDTC(
    uint8 ClientId,
    uint8* DTCStatus
);

Std_ReturnType Dem_SetDTCFilter(
    uint8 ClientId,
    uint8 DTCStatusMask,
    Dem_DTCFormatType DTCFormat,
    Dem_DTCOriginType DTCOrigin,
    boolean FilterWithSeverity,
    Dem_DTCSeverityType DTCSeverityMask,
    boolean FilterForFaultDetectionCounter
);

Std_ReturnType Dem_GetNumberOfFilteredDTC(
    uint8 ClientId,
    uint16* NumberOfFilteredDTC
);

Std_ReturnType Dem_GetNextFilteredDTC(
    uint8 ClientId,
    uint32* DTC,
    uint8* DTCStatus
);

Std_ReturnType Dem_GetNextFilteredDTCAndFDC(
    uint8 ClientId,
    uint32* DTC,
    sint8* DTCFaultDetectionCounter
);

Std_ReturnType Dem_SetDTCFilterByExtendedDataRecordNumber(
    uint8 ClientId,
    Dem_DTCFormatType DTCFormat,
    uint8 ExtendedDataRecordNumber
);

Std_ReturnType Dem_DisableDTCRecordUpdate(
    uint8 ClientId
);

Std_ReturnType Dem_EnableDTCRecordUpdate(
    uint8 ClientId
);

Std_ReturnType Dem_GetSizeOfExtendedDataRecordSelection(
    uint8 ClientId,
    uint32* SizeOfExtendedDataRecord
);

Std_ReturnType Dem_GetSizeOfFreezeFrameSelection(
    uint8 ClientId,
    uint32* SizeOfFreezeFrame
);

Std_ReturnType Dem_GetNextExtendedDataRecord(
    uint8 ClientId,
    uint8* DestBuffer,
    uint16* BufSize
);

Std_ReturnType Dem_GetNextFreezeFrameData(
    uint8 ClientId,
    uint8* DestBuffer,
    uint16* BufSize
);

Std_ReturnType Dem_SelectExtendedDataRecord(
    uint8 ClientId,
    uint8 ExtendedDataNumber
);

Std_ReturnType Dem_SelectFreezeFrameData(
    uint8 ClientId,
    uint8 RecordNumber
);

Std_ReturnType Dem_GetNumberOfFreezeFrameRecords(
    uint8 ClientId,
    uint16* NumberOfFilteredRecords
);

Std_ReturnType Dem_DisableDTCSetting (
    uint8 ClientId
);

Std_ReturnType Dem_EnableDTCSetting (
    uint8 ClientId
);

Std_ReturnType Dem_SetOperationCycleState(
    uint8 OperationCycleId,
    Dem_OperationCycleStateType CycleState
);

Std_ReturnType Dem_GetOperationCycleState(
    uint8 OperationCycleId,
    Dem_OperationCycleStateType* CycleState
);

void Dem_MainFunction(
    void
);

/** LOCAL DATA **/
static Dem_DemInfoType Dem_DemInfo[DemConf_DemClientId_Max] =
{
    {
        (Dem_DtcInfoType*)Dem_DtcInfo,
        DemConf_DemEventId_Default,
    }
};


/** GLOBAL DATA **/
Dem_DtcNvmDataType Dem_DtcNvmData[DemConf_NvmBlockId_Max];


/** LOCAL FUNCTION **/

/*******************************************************************************
* -Name            Dem_LookupNvmIndex
* -Brief           Base on the EventId search which position stored in NVM queue 
* -Details         None
* -Param[in]       ClientId: Unique client id, assigned to the instance of the calling module
* -Param[out]      nvmIndex: Pointer to the version information of this module
* -Return          E_OK: Search the NVM storage position successfully
*                  E_NOT_OK: Not have valid NVM block        
*******************************************************************************/
static Std_ReturnType Dem_LookupNvmIndex(
    Dem_EventIdType EventId,
    uint8* NvmIndex
)
{
    Std_ReturnType retVal = E_NOT_OK;
    Dem_DtcNvmDataType* DtcNvmDataPtr;
    uint8 index;

    /* Step1: Check if this fault already stored in MEM */
    for(index = DemConf_NvmBlockId_First; index < DemConf_NvmBlockId_Max; index++)
    {
        DtcNvmDataPtr = (Dem_DtcNvmDataType*)(&Dem_DtcNvmData[index]);
        if(EventId == DtcNvmDataPtr->EventId)
        {
            retVal = E_OK;
            *NvmIndex = index;
            return(retVal);
        }
    }
        
    /* Step2: Check if emity space in MEM */
    for(index = DemConf_NvmBlockId_First; index < DemConf_NvmBlockId_Max; index++)
    {
        DtcNvmDataPtr = (Dem_DtcNvmDataType*)(&Dem_DtcNvmData[index]);
        if(DemConf_NvmBlockId_Max <= DtcNvmDataPtr->EventId)
        {
            retVal = E_OK;
            *NvmIndex = index;
            return(retVal);
        }
    } 

    /* Step3: If no any emity space for new fault, cover history fault */
    for(index = DemConf_NvmBlockId_First; index < DemConf_NvmBlockId_Max; index++)
    {
        DtcNvmDataPtr = (Dem_DtcNvmDataType*)(&Dem_DtcNvmData[index]);
        if(DEM_UDS_STATUS_TF != (DtcNvmDataPtr->DtcStatus & DEM_UDS_STATUS_TF))
        {
            retVal = E_OK;
            *NvmIndex = index;
            return(retVal);
        }
    } 

   /* Step4: Not statisfy all above situations, store to first MEM fault space */
   *NvmIndex = DemConf_DemEventId_DTC_First;    
    return(retVal);
}

/*******************************************************************************
* -Name            Dem_LookupDTCEventId
* -Brief           Base on the DTC search the EventId 
* -Details         None
* -Param[in]       DTC: Defines the DTC in respective format that is selected. If the DTC fits to a DTC group number, the DTC group is selected.
* -Param[out]      EventId: Identification of an event by assigned EventId
* -Return          E_OK: Search the EventId successfully
*                  E_NOT_OK: Not map the DTC      
*******************************************************************************/
static Std_ReturnType Dem_LookupDTCEventId(
    uint32 DTC,
    Dem_EventIdType* EventId
)
{
    Std_ReturnType retVal = E_NOT_OK;
    Dem_EventIdType eventIdTemp;

    for(eventIdTemp = DemConf_DemEventId_DTC_First; eventIdTemp < DemConf_DemEventId_Max; eventIdTemp++)
    {
        if(DTC == Dem_EventParameterConfig[eventIdTemp].dtcRef->dtcValue)
        {
            retVal = E_OK;
            *EventId = eventIdTemp;
            break;
        }
    }
    return(retVal);
}

/*******************************************************************************
* -Name            Dem_LookupDTCGroupId
* -Brief           Base on the DTC search the GroupId 
* -Details         None
* -Param[in]       DTC: Defines the DTC in respective format that is selected. If the DTC fits to a DTC group number, the DTC group is selected.
* -Param[out]      EventId: Identification of an event by assigned EventId
* -Return          E_OK: Search the EventId successfully
*                  E_NOT_OK: Not map the DTC      
*******************************************************************************/
static Std_ReturnType Dem_LookupDTCGroupId(
    uint32 DTC,
    Dem_EventIdType* GroupId
)
{
    Std_ReturnType retVal = E_NOT_OK;
    Dem_EventIdType eventIdTemp;

    if(0xFFFFFFu == DTC)
    {
        *GroupId = DEM_GROUPID_ALL;
        retVal = E_OK;
    }
    return(retVal);
}


/*******************************************************************************
* -Name            Dem_ClearDTCGroup
* -Brief           Clear group DTC 
* -Details         None
* -Param[in]       ClientId: Unique client id, assigned to the instance of the calling module
* -Param[in]       DTC: DTC group number.
* -Return          E_OK: Clear group DTC successfully
*                  E_NOT_OK: Not map the DTC number 
*******************************************************************************/
static Std_ReturnType Dem_ClearDTCGroup(
    uint8 ClientId,
    Dem_GroupIdType GroupId
)
{
    Std_ReturnType retVal = E_NOT_OK;
    Dem_DemInfoType* demInfoPtr = (Dem_DemInfoType*)(&Dem_DemInfo[ClientId]);
    Dem_DtcInfoType* dtcInfoPtr;
    Dem_EventIdType eventId;
    uint8 nvmIndex;
    uint8 i;
    uint8* dataPtr;

    /* Clear all DTCs */
    if(DEM_GROUPID_ALL == GroupId)
    {
        for(eventId = DemConf_DemEventId_DTC_First; eventId < DemConf_DemEventId_Max; eventId++)
        {
            dtcInfoPtr = (Dem_DtcInfoType*)&demInfoPtr->DtcInfoRef[eventId];
            if(0x00 != dtcInfoPtr->udsStatus)
            {
                dtcInfoPtr->udsStatus = 0x00;

                dataPtr = (uint8*)dtcInfoPtr->DtcNvmDataPtr;
                for(i = 0u; i < sizeof(Dem_DtcNvmDataType); i++)
                {
                    *dataPtr = 0xFF;
                    dataPtr++;
                }
                Dem_LookupNvmIndex(eventId, &nvmIndex);
                NvM_WriteBlock(DemNvRamBlockIdMapTable[nvmIndex].DemNvRamBlockIdRef, (void*)(dtcInfoPtr->DtcNvmDataPtr));
            }
        }
        retVal = E_OK;
    }
    return(retVal);
}


/** GLOBAL FUNCTION **/

/*******************************************************************************
* -Name            Dem_GetVersionInfo
* -Brief           Returns the version information of this module 
* -Details         None
* -Param[out]      versioninfo: Pointer to the version information of this module
* -Return          None          
*******************************************************************************/
void Dem_GetVersionInfo(
    Std_VersionInfoType* versionInfo
)
{
    versionInfo->vendorID = (uint16)YSAR_VENDOR_ID;
    versionInfo->moduleID = (uint8)DEM_MODULE_ID;
    versionInfo->sw_major_version = (uint8)DEM_SW_MAJOR_VERSION;
    versionInfo->sw_minor_version = (uint8)DEM_SW_MINOR_VERSION;
    versionInfo->sw_patch_version = (uint8)DEM_SW_PATCH_VERSION;
}


/*******************************************************************************
* -Name            Dem_ClearDTC
* -Brief           Clears single DTCs, as well as groups of DTCs 
* -Details         None
* -Param[in]       ClientId: Unique client id, assigned to the instance of the calling module
* -Return          E_OK: DTC successfully cleared 
                   E_NOT_OK: No DTC selected 
                   DEM_WRONG_DTC: Selected DTC value in selected format does not exist or clearing is restricted by configuration to group of all DTCs only. 
                   DEM_WRONG_DTCORIGIN: Selected DTCOrigin does not exist DEM_CLEAR_FAILED: DTC clearing failed 
                   DEM_CLEAR_BUSY: Another client is currently clearing DTCs. The requested operation will not be started and the caller shall try again at a later moment. 
                   DEM_CLEAR_MEMORY_ERROR: An error occurred during erasing a memory location (e.g. if DemClearDTCBehavior is set to 
                   DEM_CLRRESP_NON-VOLATILE_FINISH and erasing of non-volatile-block failed). 
                   DEM_PENDING: Clearing the DTCs is currently in progress. The caller shall call this function again at a later moment. 
                   DEM_BUSY: A different Dem_SelectDTC dependent operation according to SWS_Dem_01253 of this client is currently in progress.       
*******************************************************************************/
Std_ReturnType Dem_ClearDTC(
    uint8 ClientId
)
{
    Std_ReturnType retVal = E_OK;
    Dem_DemInfoType* demInfoPtr = (Dem_DemInfoType*)(&Dem_DemInfo[ClientId]);
    
    Dem_ClearDTCGroup(ClientId, demInfoPtr->SelectedGroupId);
    
    return(retVal);
}


/*******************************************************************************
* -Name            Dem_SetEventStatus
* -Brief           Called by SW-Cs or BSW modules to report monitor status information to the Dem
* -Details         None
* -Param[in]       EventId: Identification of an event by assigned EventId
* -Param[in]       EventStatus: Monitor test result
* -Return          E_OK: set of event status was successful
*                  E_NOT_OK: Event status setting or processing failed or could not be accepted
*******************************************************************************/
Std_ReturnType Dem_SetEventStatus(
    Dem_EventIdType EventId,
    Dem_EventStatusType EventStatus
)
{
    Dem_DemInfoType* demInfoPtr = (Dem_DemInfoType*)(&Dem_DemInfo[DemConf_DemClientId_01]); 
    Dem_DtcInfoType* dtcInfoPtr = (Dem_DtcInfoType*)&Dem_DtcInfo[EventId];
    Dem_EventParameterType* eventParameterConfigPtr = (Dem_EventParameterType*)&Dem_EventParameterConfig[EventId];

    if(RESET == demInfoPtr->DtcDisableFlag)
    {
        switch(EventStatus)
        {
            case DEM_EVENT_STATUS_PASSED:
            {
                dtcInfoPtr->faultDetCounter = DEM_CFG_COUNTER_PASSED_THRESHOLD(eventParameterConfigPtr);
                break;
            }
            case DEM_EVENT_STATUS_FAILED:
            {
                dtcInfoPtr->faultDetCounter = DEM_CFG_COUNTER_FAILED_THRESHOLD(eventParameterConfigPtr);
                break;
            }
            case DEM_EVENT_STATUS_PREPASSED:
            {
                if(DEM_EVENT_STATUS_PREFAILED == dtcInfoPtr->eventStatusOld)
                {
                    if(SET == DEM_CFG_COUNTER_JUMPDOWN(eventParameterConfigPtr))
                    {
                        dtcInfoPtr->faultDetCounter = DEM_CFG_COUNTER_JUMPDOWN_VALUE(eventParameterConfigPtr);
                    }
                }
                if(dtcInfoPtr->faultDetCounter >=  (DEM_CFG_COUNTER_PASSED_THRESHOLD(eventParameterConfigPtr) + DEM_CFG_COUNTER_DECREMENT_STEP_SIZE(eventParameterConfigPtr)))
                {
                    dtcInfoPtr->faultDetCounter = dtcInfoPtr->faultDetCounter - DEM_CFG_COUNTER_DECREMENT_STEP_SIZE(eventParameterConfigPtr);
                }
                else
                {
                    dtcInfoPtr->faultDetCounter = DEM_CFG_COUNTER_PASSED_THRESHOLD(eventParameterConfigPtr);
                }
                

                break;
            }
            case DEM_EVENT_STATUS_PREFAILED:
            {
                if(DEM_EVENT_STATUS_PREPASSED == dtcInfoPtr->eventStatusOld)
                {
                    if(SET == DEM_CFG_COUNTER_JUMPUP(eventParameterConfigPtr))
                    {
                        dtcInfoPtr->faultDetCounter = DEM_CFG_COUNTER_JUMPUP_VALUE(eventParameterConfigPtr);
                    }
                }
                if((dtcInfoPtr->faultDetCounter + DEM_CFG_COUNTER_INCREMENT_STEP_SIZE(eventParameterConfigPtr)) <= DEM_CFG_COUNTER_FAILED_THRESHOLD(eventParameterConfigPtr))
                {
                    dtcInfoPtr->faultDetCounter = dtcInfoPtr->faultDetCounter + DEM_CFG_COUNTER_INCREMENT_STEP_SIZE(eventParameterConfigPtr);
                }
                else
                {
                    dtcInfoPtr->faultDetCounter = DEM_CFG_COUNTER_FAILED_THRESHOLD(eventParameterConfigPtr);
                }
                
                break;

                break;
            }
            case DEM_EVENT_STATUS_FDC_THRESHOLD_REACHED:
            {
                break;
            }
            
            default:
            {
                break;
            }
        }
    }

    dtcInfoPtr->eventStatusOld = EventStatus;
}

/*******************************************************************************
* -Name            Dem_SetEventStatusWithMonitorData
* -Brief           None
* -Details         None
* -Param[in]       EventId: Identification of an event by assigned EventId
* -Param[in]       EventStatus: Monitor test result
* -Param[in]       monitorData0: Monitor data0
* -Param[in]       monitorData1: Monitor data1
* -Return          E_OK: set of event status was successful
*                  E_NOT_OK: Event status setting or processing failed or could not be accepted
*******************************************************************************/
Std_ReturnType Dem_SetEventStatusWithMonitorData(
    Dem_EventIdType EventId,
    Dem_EventStatusType EventStatus,
    Dem_MonitorDataType monitorData0,
    Dem_MonitorDataType monitorData1
)
{
    
}

/*******************************************************************************
* -Name            Dem_GetDTCStatusAvailabilityMask
* -Brief           Gets the DTC Status availability mask of the selected fault memory
* -Details         None
* -Param[in]       EventId: Identification of an event by assigned EventId
* -Param[in]       DTCOrigin: This parameter selects the event memory the DTCStatus AvailabilityMask is requested for
* -Param[out]      DTCStatusMask: DTCStatusMask The value DTCStatusMask indicates the supported DTC status bits from the Dem.
* -Return          E_OK: get of DTC status mask was successful
*                  E_NOT_OK: get of DTC status mask failed
*******************************************************************************/
Std_ReturnType Dem_GetDTCStatusAvailabilityMask(
    uint8 ClientId,
    Dem_UdsStatusByteType* DTCStatusMask,
    Dem_DTCOriginType DTCOrigin
)
{
    Dem_EventMemorySetType* eventMemorySetPtr = (Dem_EventMemorySetType*)&Dem_EventMemorySetConfig[0u];
    
    *DTCStatusMask = eventMemorySetPtr->DemPrimaryMemory.DemDtcStatusAvailabilityMask;
}


/*******************************************************************************
* -Name            Dem_GetStatusOfDTC
* -Brief           Gets the status of a DTC.
* -Details         None
* -Param[in]       ClientId: Unique client id, assigned to the instance of the calling module
* -Param[out]      DTCStatus: This parameter receives the status information of the requested DTC
* -Return          E_OK: The status of the DTC is correctly provided in the DTCStatus parameter
*                  E_NOT_OK: No DTC selected
*                  DEM_WRONG_DTC: Selected DTC value in selected format does not exist
*                  DEM_WRONG_DTCORIGIN: Selected DTCOrigin does not exist
*                  DEM_PENDING: Retrieving the DTC status is currently in progress. The caller shall 
*                               call this function again at a later moment
*                  DEM_NO_SUCH_ELEMENT: Selected DTC does not have an assigned DTC status.
*                  DEM_BUSY: A different Dem_SelectDTC dependent operation according to SWS_Dem_01253 
*                            of this client is currently in progress
*******************************************************************************/
Std_ReturnType Dem_GetStatusOfDTC(
    uint8 ClientId,
    uint8* DTCStatus
)
{
    Std_ReturnType retVal = E_OK;
    Dem_DemInfoType* demInfoPtr = (Dem_DemInfoType*)(&Dem_DemInfo[ClientId]);
    
    *DTCStatus = demInfoPtr->DtcInfoRef[demInfoPtr->SelectedEventId].udsStatus;
    
    return(retVal);
}

/*******************************************************************************
* -Name            Dem_SetDTCFilter
* -Brief           Sets the DTC Filter
* -Details         None
* -Param[in]       ClientId: Unique client id, assigned to the instance of the calling module
* -Param[in]       DTCStatusMask: Defines the output-format of the requested DTC values for the sub-sequent API calls
* -Param[in]       DTCOrigin: 
* -Param[in]       FilterWithSeverity: This flag defines whether severity information
* -Param[in]       DTCSeverityMask: Contains the DTCSeverityMask according to ISO14229-1
* -Param[in]       FilterForFaultDetectionCounter: This flag defines whether the fault detection counter information
                                                   shall be used for filtering.
* -Param[out]      DTCStatus: This parameter receives the status information of the requested DTC
* -Return          E_OK: Getting number of filtered DTCs was successful
*                  E_NOT_OK: No DTC filter set
*                  DEM_PENDING: The requested operation is currently in progress
*******************************************************************************/
Std_ReturnType Dem_SetDTCFilter(
    uint8 ClientId,
    uint8 DTCStatusMask,
    Dem_DTCFormatType DTCFormat,
    Dem_DTCOriginType DTCOrigin,
    boolean FilterWithSeverity,
    Dem_DTCSeverityType DTCSeverityMask,
    boolean FilterForFaultDetectionCounter
)
{
    Std_ReturnType retVal = E_OK;
    Dem_DemInfoType* demInfoPtr = (Dem_DemInfoType*)(&Dem_DemInfo[ClientId]);

    demInfoPtr->StatusMask = DTCStatusMask;
    demInfoPtr->SelectedEventId = 0u;

    return(retVal);
}

/*******************************************************************************
* -Name            Dem_GetNumberOfFilteredDTC
* -Brief           Gets the number of a filtered DTC
* -Details         None
* -Param[in]       ClientId: Unique client id, assigned to the instance of the calling module
* -Param[out]      NumberOfFilteredDTC: The number of DTCs matching the defined status mask
* -Return          E_OK: Filter was successfully set
*                  E_NOT_OK: Indicates a wrong DTCOrigin or DTCFormat
*******************************************************************************/
Std_ReturnType Dem_GetNumberOfFilteredDTC(
    uint8 ClientId,
    uint16* NumberOfFilteredDTC
)
{
    Std_ReturnType retVal = E_OK;
    Dem_DemInfoType* demInfoPtr = (Dem_DemInfoType*)(&Dem_DemInfo[ClientId]);
    uint16 counter = 0u;
    Dem_EventIdType eventId;

    for(eventId = 0u; eventId < DemConf_DemEventId_Max; eventId++)
    {
        if(0u != (demInfoPtr->StatusMask & demInfoPtr->DtcInfoRef[eventId].udsStatus))
        {
            counter++;
        }
    }
    *NumberOfFilteredDTC = counter;
    
    return(retVal);
}

/*******************************************************************************
* -Name            Dem_GetNextFilteredDTC
* -Brief           Gets the next filtered DTC matching the filter criteria
* -Details         None
* -Param[in]       ClientId: Unique client id, assigned to the instance of the calling module
* -Param[out]      DTC: Receives the DTC value in respective format of the filter
* -Param[out]      DTCStatus: This parameter receives the status information of the requested DTC
* -Return          E_OK: Returned next filtered element
*                  E_NOT_OK: No DTC filter set
*                  DEM_NO_SUCH_ELEMENT: No further element matching the filter criteria found
*                  DEM_PENDING: The requested operation is currently in progress
*******************************************************************************/
Std_ReturnType Dem_GetNextFilteredDTC(
    uint8 ClientId,
    uint32* DTC,
    uint8* DTCStatus
)
{
    Std_ReturnType retVal = E_NOT_OK;
    
    Dem_DemInfoType* demInfoPtr = (Dem_DemInfoType*)(&Dem_DemInfo[ClientId]);
    Dem_DTCType* dtcCfgPtr;

    for(; demInfoPtr->SelectedEventId < DemConf_DemEventId_Max; demInfoPtr->SelectedEventId++)
    {
        *DTCStatus = demInfoPtr->DtcInfoRef[demInfoPtr->SelectedEventId].udsStatus;
        
        if(0u != (demInfoPtr->StatusMask & (*DTCStatus)))
        {
            dtcCfgPtr = Dem_EventParameterConfig[demInfoPtr->SelectedEventId].dtcRef;
            *DTC = dtcCfgPtr->dtcValue; 
            demInfoPtr->SelectedEventId++;
            retVal = E_OK;
            break;
        }
        else if(0x00 == demInfoPtr->StatusMask)
        {
            dtcCfgPtr = Dem_EventParameterConfig[demInfoPtr->SelectedEventId].dtcRef;
            *DTC = dtcCfgPtr->dtcValue;
            demInfoPtr->SelectedEventId++;
            retVal = E_OK;
            break;
        }
        else
        {
            /* Do nothing */
        }
    }

    return(retVal);
}

/*******************************************************************************
* -Name            Dem_GetNextFilteredDTC
* -Brief           Gets the next filtered DTC and its associated Fault Detection Counter (FDC) matching the filter criteria
* -Details         None
* -Param[in]       ClientId: Unique client id, assigned to the instance of the calling module
* -Param[out]      DTC: Receives the DTC value in respective format of the filter
* -Param[out]      DTCFaultDetectionCounter: This parameter receives the Fault Detection Counter information
* -Return          E_OK: Returned next filtered element
*                  E_NOT_OK: No DTC filter set
*                  DEM_NO_SUCH_ELEMENT: No further element matching the filter criteria found
*                  DEM_PENDING: The requested operation is currently in progress
*******************************************************************************/
Std_ReturnType Dem_GetNextFilteredDTCAndFDC(
    uint8 ClientId,
    uint32* DTC,
    sint8* DTCFaultDetectionCounter
)
{
    
}

/*******************************************************************************
* -Name            Dem_SetDTCFilterByExtendedDataRecordNumber
* -Brief           Sets the DTC Filter based on a given extended data record on the primary fault memory
* -Details         None
* -Param[in]       ClientId: Unique client id, assigned to the instance of the calling module
* -Param[in]       DTCFormat: Defines the DTC format of the requested data.
* -Param[in]       ExtendedDataRecordNumber: hex extended data record number the filter is set for
* -Return          E_OK: Returned next filtered element
*                  E_NOT_OK: No DTC filter set
*                  DEM_NO_SUCH_ELEMENT: No further element matching the filter criteria found
*                  DEM_PENDING: The requested operation is currently in progress
*******************************************************************************/
Std_ReturnType Dem_SetDTCFilterByExtendedDataRecordNumber(
    uint8 ClientId,
    Dem_DTCFormatType DTCFormat,
    uint8 ExtendedDataRecordNumber
)
{
    
}

/*******************************************************************************
* -Name            Dem_DisableDTCRecordUpdate
* -Brief           Disables the event memory update of a specific DTC (only one at one time)
* -Details         None
* -Param[in]       ClientId: Unique client id, assigned to the instance of the calling module
* -Return          E_OK: Event memory update successfully disabled
*                  E_NOT_OK: No DTC selected
*                  DEM_WRONG_DTC: Selected DTC value in selected format does not exist or a group of DTC was selected
*                  DEM_WRONG_DTCORIGIN: Selected DTCOrigin does not exist
*                  DEM_PENDING: Disabling the DTC record update is currently in progress
*                  DEM_BUSY: A different Dem_SelectDTC dependent operation in progress
*******************************************************************************/
Std_ReturnType Dem_DisableDTCRecordUpdate(
    uint8 ClientId
)
{
    
}

/*******************************************************************************
* -Name            Dem_EnableDTCRecordUpdate
* -Brief           Enables the event memory update
* -Details         None
* -Param[in]       ClientId: Unique client id, assigned to the instance of the calling module
* -Return          E_OK: Event memory update successfully disabled
*                  E_NOT_OK: No DTC selected
*******************************************************************************/
Std_ReturnType Dem_EnableDTCRecordUpdate(
    uint8 ClientId
)
{
    
}

/*******************************************************************************
* -Name            Dem_GetSizeOfExtendedDataRecordSelection
* -Brief           Gets the next filtered DTC and its associated Fault Detection Counter (FDC) matching the filter criteria
* -Details         None
* -Param[in]       ClientId: Unique client id, assigned to the instance of the calling module
* -Param[out]      SizeOfExtendedDataRecord: Size of the requested extended data record(s) including record number
* -Return          E_OK: Size returned successfully
*                  E_NOT_OK: selection function is not called
*                  DEM_PENDING: The requested value is calculated asynchronously and currently not available
*                  DEM_WRONG_DTC: DTC value not existing
*                  DEM_WRONG_DTCORIGIN: Wrong DTC origin
*                  DEM_NO_SUCH_ELEMENT: Record number is not supported by configuration and therefore invalid
*******************************************************************************/
Std_ReturnType Dem_GetSizeOfExtendedDataRecordSelection(
    uint8 ClientId,
    uint32* SizeOfExtendedDataRecord
)
{
    
}

/*******************************************************************************
* -Name            Dem_GetSizeOfFreezeFrameSelection
* -Brief           Gets the size of freeze frame data by DTC selected by the call of Dem_SelectFreezeFrame data
* -Details         None
* -Param[in]       ClientId: Unique client id, assigned to the instance of the calling module
* -Param[out]      SizeOfFreezeFrame: Number of bytes in the requested freeze frame record
* -Return          E_OK: Size returned successfully
*                  E_NOT_OK: selection function is not called
*                  DEM_PENDING: The requested value is calculated asynchronously and currently not available
*                  DEM_WRONG_DTC: DTC value not existing
*                  DEM_WRONG_DTCORIGIN: Wrong DTC origin
*                  DEM_NO_SUCH_ELEMENT: Record number is not supported by configuration and therefore invalid
*******************************************************************************/
Std_ReturnType Dem_GetSizeOfFreezeFrameSelection(
    uint8 ClientId,
    uint32* SizeOfFreezeFrame
)
{
    
}

/*******************************************************************************
* -Name            Dem_GetNextExtendedDataRecord
* -Brief           Gets extended data record for the DTC selected by Dem_SelectExtendedDataRecord
* -Details         None
* -Param[in]       ClientId: Unique client id, assigned to the instance of the calling module
* -Param[inout]    BufSize: When the function is called this parameter contains the maximum number of data bytes that can be written to the buffer
* -Param[out]      DestBuffer: This parameter contains a byte pointer that points to the buffer
* -Return          E_OK: Size and buffer successfully returned
*                  E_NOT_OK: selection function is not called
*                  DEM_BUFFER_TOO_SMALL: provided buffer size too small
*                  DEM_PENDING: The requested value is calculated asynchronously and currently not available. The caller can retry later
*                  DEM_WRONG_DTC: DTC value not existing
*                  DEM_WRONG_DTCORIGIN: Wrong DTC origin
*                  DEM_NO_SUCH_ELEMENT: Found no (further) element matching the filter criteria
*******************************************************************************/
Std_ReturnType Dem_GetNextExtendedDataRecord(
    uint8 ClientId,
    uint8* DestBuffer,
    uint16* BufSize
)
{
    Std_ReturnType retVal = E_OK;
    Dem_DemInfoType* demInfoPtr = (Dem_DemInfoType*)(&Dem_DemInfo[ClientId]);     
    Dem_EventParameterType*  eventParameterConfigPtr = (Dem_EventParameterType*)&Dem_EventParameterConfig[demInfoPtr->SelectedEventId];
    DemExtendedDataClassType* extendedDataClassConfigPtr = (DemExtendedDataClassType*)(&eventParameterConfigPtr->dtcRef->dtcAttributesRef->DemExtendedDataClassRef[demInfoPtr->ExtendedDataNumberIndex]);;
    Dem_DtcNvmDataType* dtcNvmDataPtr = demInfoPtr->DtcInfoRef[demInfoPtr->SelectedEventId].DtcNvmDataPtr;
    uint8 i;
    uint8 resDataIndex = 0u;

    DestBuffer[resDataIndex] = extendedDataClassConfigPtr->DemExtendedDataRecordClassRef->DemExtendedDataRecordNumber;
    *BufSize = 1u;
    resDataIndex = 1u;
    for(i = 0; i < extendedDataClassConfigPtr->DemExtendedDataRecordClassRef->DemDataElementClassRefIndexMax; i++)
    {
        extendedDataClassConfigPtr->DemExtendedDataRecordClassRef->DemDataElementClassRef[i].DemExternalCSDataElementClass.DemDataElementReadFnc(dtcNvmDataPtr, *BufSize, (uint8*)&DestBuffer[resDataIndex]);
        resDataIndex = resDataIndex + extendedDataClassConfigPtr->DemExtendedDataRecordClassRef->DemDataElementClassRef->DemExternalCSDataElementClass.DemDataElementArraySize;
        *BufSize += extendedDataClassConfigPtr->DemExtendedDataRecordClassRef->DemDataElementClassRef->DemExternalCSDataElementClass.DemDataElementArraySize;
    }

    if(DTCExtendedDataRecordNumber_0xFF == demInfoPtr->SelectedExtendedDataNumber)
    {
        demInfoPtr->ExtendedDataNumberIndex++;
        if(eventParameterConfigPtr->dtcRef->dtcAttributesRef->DemMaxNumberExtendedDataRecords <= demInfoPtr->ExtendedDataNumberIndex)
        {
            retVal = DEM_NO_SUCH_ELEMENT;
        }
    }
    else
    {
        retVal = DEM_NO_SUCH_ELEMENT;
    }

    return(retVal);
}

/*******************************************************************************
* -Name            Dem_GetNextFreezeFrameData
* -Brief           Gets freeze frame data by the DTC selected by Dem_SelectFreezeFrameData
* -Details         None
* -Param[in]       ClientId: Unique client id, assigned to the instance of the calling module
* -Param[inout]    BufSize: When the function is called this parameter contains the maximum number of data bytes that can be written to the buffer
* -Param[out]      DestBuffer: This parameter contains a byte pointer that points to the buffer
* -Return          E_OK: Size and buffer successfully returned
*                  E_NOT_OK: selection function is not called
*                  DEM_BUFFER_TOO_SMALL: provided buffer size too small
*                  DEM_PENDING: The requested value is calculated asynchronously and currently not available. The caller can retry later
*                  DEM_WRONG_DTC: DTC value not existing
*                  DEM_WRONG_DTCORIGIN: Wrong DTC origin
*                  DEM_NO_SUCH_ELEMENT: Found no (further) element matching the filter criteria
*******************************************************************************/
Std_ReturnType Dem_GetNextFreezeFrameData(
    uint8 ClientId,
    uint8* DestBuffer,
    uint16* BufSize
)
{
    Std_ReturnType retVal = E_OK;
    Dem_DemInfoType* demInfoPtr = (Dem_DemInfoType*)(&Dem_DemInfo[ClientId]);     
    Dem_EventParameterType*  eventParameterConfigPtr = (Dem_EventParameterType*)&Dem_EventParameterConfig[demInfoPtr->SelectedEventId];
    DemFreezeFrameClassType* freezeFrameClassConfigPtr = (DemFreezeFrameClassType*)(&eventParameterConfigPtr->dtcRef->dtcAttributesRef->DemFreezeFrameClassRef[demInfoPtr->SnapshotRecordNumberIndex]);
    DemDidClassType* didClassConfigPtr;
    DemFreezeFrameRecordClassType* freezeFrameRecordClassPtr = eventParameterConfigPtr->dtcRef->dtcAttributesRef->DemFreezeFrameRecNumClassRef->freezeFrameRecordClassRef[demInfoPtr->SnapshotRecordNumberIndex];
    Dem_DtcNvmDataType* dtcNvmDataPtr = demInfoPtr->DtcInfoRef[demInfoPtr->SelectedEventId].DtcNvmDataPtr;
    uint8 i;
    uint8 j;
    uint8 resDataIndex = 0u;

    DestBuffer[0u] = freezeFrameRecordClassPtr->DemFreezeFrameRecordNumber;
    DestBuffer[1u] = freezeFrameClassConfigPtr->DemDidClassRefIndexMax;
    *BufSize = 2u;
    resDataIndex = 2u;
    for(i = 0u; i < freezeFrameClassConfigPtr->DemDidClassRefIndexMax; i++)
    {
        didClassConfigPtr = (DemDidClassType*)&freezeFrameClassConfigPtr->DemDidClassRef[i];
        DestBuffer[resDataIndex] = (uint8)(didClassConfigPtr->DemDidIdentifier >> 8u);
        DestBuffer[resDataIndex + 1u] = (uint8)(didClassConfigPtr->DemDidIdentifier);
        resDataIndex += 2u;
        *BufSize += 2u;

        for(j = 0u; j < didClassConfigPtr->DemDidDataElementClassRefIndexMax; j++)
        {
            didClassConfigPtr->DemDidDataElementClassRef[j].DemExternalCSDataElementClass.DemDataElementReadFnc(dtcNvmDataPtr, *BufSize, (uint8*)&DestBuffer[resDataIndex]);
            resDataIndex = resDataIndex + didClassConfigPtr->DemDidDataElementClassRef[j].DemExternalCSDataElementClass.DemDataElementArraySize;
            *BufSize += didClassConfigPtr->DemDidDataElementClassRef[j].DemExternalCSDataElementClass.DemDataElementArraySize;
        }
    }

    if(DTCSnapshotRecordNumber_0xFF == demInfoPtr->SelectedSnapshotRecordNumber)
    {
        demInfoPtr->SnapshotRecordNumberIndex++;
        if(eventParameterConfigPtr->dtcRef->dtcAttributesRef->DemMaxNumberFreezeFrameRecords <= demInfoPtr->SnapshotRecordNumberIndex)
        {
            retVal = DEM_NO_SUCH_ELEMENT;
        }
    }
    else
    {
        retVal = DEM_NO_SUCH_ELEMENT;
    }

    return(retVal);
}

/*******************************************************************************
* -Name            Dem_SelectExtendedDataRecord
* -Brief           Sets the filter to be used by Dem_GetNextExtendedDataRecord and Dem_GetSizeOfExtended DataRecordSelection
* -Details         None
* -Param[in]       ClientId: Unique client id, assigned to the instance of the calling module
* -Param[in]       ExtendedDataNumber: Identification/Number of requested extended data record
* -Return          E_OK: Extended data record successfully selected
*                  DEM_WRONG_DTC: Selected DTC value in selected format does not exist
*                  DEM_WRONG_DTCORIGIN: Selected DTCOrigin does not exist
*                  DEM_PENDING: Selecting the extended data record is currently in progress
*                  DEM_BUSY: A different Dem_SelectDTC dependent operation in progress
*******************************************************************************/
Std_ReturnType Dem_SelectExtendedDataRecord(
    uint8 ClientId,
    uint8 ExtendedDataNumber
)
{
    Std_ReturnType retVal = E_NOT_OK;
    Dem_DemInfoType* demInfoPtr = (Dem_DemInfoType*)(&Dem_DemInfo[ClientId]);     
    Dem_EventParameterType*  eventParameterConfigPtr = (Dem_EventParameterType*)&Dem_EventParameterConfig[demInfoPtr->SelectedEventId];
    DemExtendedDataClassType* extendedDataClassConfigPtr;
    uint8 i;
    
    demInfoPtr->SelectedExtendedDataNumber = ExtendedDataNumber;
    if(DTCExtendedDataRecordNumber_0xFF == demInfoPtr->SelectedExtendedDataNumber)
    {
        demInfoPtr->ExtendedDataNumberIndex = 0u;
        retVal = E_OK;
    }
    else
    {
        demInfoPtr->ExtendedDataNumberIndex = eventParameterConfigPtr->dtcRef->dtcAttributesRef->DemMaxNumberExtendedDataRecords;
        for(i = 0u; i < eventParameterConfigPtr->dtcRef->dtcAttributesRef->DemMaxNumberExtendedDataRecords; i++)
        {
            extendedDataClassConfigPtr = (DemExtendedDataClassType*)(&eventParameterConfigPtr->dtcRef->dtcAttributesRef->DemExtendedDataClassRef[i]);
            if(ExtendedDataNumber == extendedDataClassConfigPtr->DemExtendedDataRecordClassRef->DemExtendedDataRecordNumber)
            {
                demInfoPtr->ExtendedDataNumberIndex = i;
                retVal = E_OK;
                break;
            }
        }
    }
    
    return(retVal);
}

/*******************************************************************************
* -Name            Dem_SelectFreezeFrameData
* -Brief           Sets the filter to be used by Dem_GetNextFreezeFrameData and Dem_GetSizeOfFreezeFrame Selection
* -Details         None
* -Param[in]       ClientId: Unique client id, assigned to the instance of the calling module
* -Param[in]       RecordNumber: Unique identifier for a snapshot record as defined in ISO 14229-1
* -Return          E_OK: Extended data record successfully selected
*                  DEM_WRONG_DTC: Selected DTC value in selected format does not exist
*                  DEM_WRONG_DTCORIGIN: Selected DTCOrigin does not exist
*                  DEM_PENDING: Selecting the extended data record is currently in progress
*                  DEM_BUSY: A different Dem_SelectDTC dependent operation in progress
*******************************************************************************/
Std_ReturnType Dem_SelectFreezeFrameData(
    uint8 ClientId,
    uint8 RecordNumber
)
{
    Std_ReturnType retVal = E_NOT_OK;
    Dem_DemInfoType* demInfoPtr = (Dem_DemInfoType*)(&Dem_DemInfo[ClientId]);     
    Dem_EventParameterType*  eventParameterConfigPtr = (Dem_EventParameterType*)&Dem_EventParameterConfig[demInfoPtr->SelectedEventId];
    DemFreezeFrameRecordClassType* freezeFrameRecordClassPtr;
    uint8 i;
    
    demInfoPtr->SelectedSnapshotRecordNumber = RecordNumber;
    if(DTCSnapshotRecordNumber_0xFF == demInfoPtr->SelectedSnapshotRecordNumber)
    {
        demInfoPtr->SnapshotRecordNumberIndex = 0u;
        retVal = E_OK;
    }
    else
    {
        demInfoPtr->SnapshotRecordNumberIndex = eventParameterConfigPtr->dtcRef->dtcAttributesRef->DemMaxNumberFreezeFrameRecords;
        for(i = 0u; i < eventParameterConfigPtr->dtcRef->dtcAttributesRef->DemMaxNumberFreezeFrameRecords; i++)
        {
            freezeFrameRecordClassPtr = eventParameterConfigPtr->dtcRef->dtcAttributesRef->DemFreezeFrameRecNumClassRef->freezeFrameRecordClassRef[i];
            if(RecordNumber == freezeFrameRecordClassPtr->DemFreezeFrameRecordNumber)
            {
                demInfoPtr->SnapshotRecordNumberIndex = i;
                retVal = E_OK;
                break;
            }
        }
    }
    
    return(retVal);
}

/*******************************************************************************
* -Name            Dem_GetNumberOfFreezeFrameRecords
* -Brief           This function returns the number of all freeze frame records currently stored in the primary event memory
* -Details         None
* -Param[in]       ClientId: Unique client id, assigned to the instance of the calling module
* -Param[out]      NumberOfFilteredRecords: Number of all freeze frame records currently stored in the primary event memory
* -Return          E_OK: Returned correctly the number of freeze frame records
*                  DEM_PENDING: The requested value is calculated asynchronously and currently not available. The caller can retry later
*******************************************************************************/
Std_ReturnType Dem_GetNumberOfFreezeFrameRecords(
    uint8 ClientId,
    uint16* NumberOfFilteredRecords
)
{
    
}

/*******************************************************************************
* -Name            Dem_SelectDTC
* -Brief           Selects a DTC or DTC group as target for further operations
* -Details         None
* -Param[in]       ClientId: Unique client id, assigned to the instance of the calling module
* -Param[in]       DTC: Defines the DTC in respective format that is selected. If the DTC fits to a DTC group number, the DTC group is selected.
* -Param[in]       DTCFormat: Defines the input-format of the provided DTC value
* -Param[in]       DTCOrigin: The event memory of the requested DTC or group of DTC
* -Param[out]      None
* -Return          E_OK: DTC successfully selected
*                  DEM_BUSY: Another Dem_SelectDTC or Dem_SelectDTC dependent operation of this client is currently in progress
*******************************************************************************/
Std_ReturnType Dem_SelectDTC(
    uint8 ClientId,
    uint32 DTC,
    Dem_DTCFormatType DTCFormat,
    Dem_DTCOriginType DTCOrigin
)
{
    Std_ReturnType retVal = E_NOT_OK;
    Dem_EventIdType eventId;
    Dem_GroupIdType groupId;
    Dem_DemInfoType* demInfoPtr = (Dem_DemInfoType*)(&Dem_DemInfo[ClientId]);
    
    retVal = Dem_LookupDTCEventId(DTC, &eventId);
    if(E_OK == retVal)
    {
        demInfoPtr->SelectedEventId = eventId;
    }
    else
    {
        retVal = Dem_LookupDTCGroupId(DTC, &groupId);
        if(E_OK == retVal)
        {
            demInfoPtr->SelectedGroupId = groupId;
        }
    }

    return(retVal);
}

/*******************************************************************************
* -Name            Dem_DisableDTCSetting
* -Brief           Disables the DTC setting for all DTCs assigned to the DemEventMemorySet of the addressed client
* -Details         None
* -Param[in]       ClientId: Unique client id, assigned to the instance of the calling module
* -Param[out]      None
* -Return          E_OK: Returned next filtered element
*                  DEM_PENDING: The requested operation is currently in progress. The caller shall call this function again at a later moment
*******************************************************************************/
Std_ReturnType Dem_DisableDTCSetting (
    uint8 ClientId
)
{
    Std_ReturnType retVal = E_OK;
    Dem_DemInfoType* demInfoPtr = (Dem_DemInfoType*)(&Dem_DemInfo[ClientId]); 

    demInfoPtr->DtcDisableFlag = SET;

    return(retVal);
}

/*******************************************************************************
* -Name            Dem_EnableDTCSetting
* -Brief           (Re)-Enables the DTC setting for all DTCs assigned to the DemEventMemorySet of the addressed client
* -Details         None
* -Param[in]       ClientId: Unique client id, assigned to the instance of the calling module
* -Param[out]      None
* -Return          E_OK: Returned next filtered element
*                  DEM_PENDING: The requested operation is currently in progress. The caller shall call this function again at a later moment
*******************************************************************************/
Std_ReturnType Dem_EnableDTCSetting (
    uint8 ClientId
)
{
    Std_ReturnType retVal = E_OK;
    Dem_DemInfoType* demInfoPtr = (Dem_DemInfoType*)(&Dem_DemInfo[ClientId]);

    demInfoPtr->DtcDisableFlag = RESET;

    return(retVal);
}

/*******************************************************************************
* -Name            Dem_SetOperationCycleState
* -Brief           Sets an operation cycle state. This API can only be used through the
                   RTE and therefore no declaration is exported via Dem.h.
                   The interface has an asynchronous behavior to avoid exceeding of typical
                   timing requirements on APIs if a large number of events has to be processed
                   and during the re-initializations of the related monitors. The a synchronous
                   acknowledgements are the related InitMonitorForEvent call backs.
* -Details         None
* -Param[in]       OperationCycleId:  Identification of operationcycle, like power cycle, driving cycle.
* -Param[in]       CycleState: New operation cycle state: (re-)start or end
* -Param[out]      None
* -Return          E_OK: set of operation cycle was accepted and will be handled asynchronously
*                  E_NOT_OK: set of operation cycle was rejected
*******************************************************************************/
Std_ReturnType Dem_SetOperationCycleState(
    uint8 OperationCycleId,
    Dem_OperationCycleStateType CycleState
)
{
    Dem_EventIdType eventId;
    Dem_DtcInfoType* dtcInfoPtr;
    Dem_EventParameterType* eventParameterConfigPtr;
    uint8 nvmIndex;

    for(eventId = 0u; eventId < DemConf_DemEventId_Max; eventId++)
    {
        dtcInfoPtr = (Dem_DtcInfoType*)&Dem_DtcInfo[eventId];
        eventParameterConfigPtr = (Dem_EventParameterType*)&Dem_EventParameterConfig[eventId];

        if(OperationCycleId == eventParameterConfigPtr->operationCycleRef->DemOperationCycleId)
        {
            if(DEM_CYCLE_STATE_END == CycleState)
            {
                if((DEM_UDS_STATUS_CDTC == (dtcInfoPtr->udsStatus & DEM_UDS_STATUS_CDTC))
                  && (DEM_UDS_STATUS_TFTOC != (dtcInfoPtr->udsStatus & DEM_UDS_STATUS_TFTOC)))
                {
                    Dem_LookupNvmIndex(eventId, &nvmIndex);
                    if(eventParameterConfigPtr->dtcRef->dtcAttributesRef->DemAgingCycleCounterThreshold > dtcInfoPtr->DtcNvmDataPtr->ExtendedDataAgingCounter)
                    {
                        dtcInfoPtr->DtcNvmDataPtr->ExtendedDataAgingCounter++;
                    }
                    else
                    {
                        dtcInfoPtr->udsStatus = 0x00;
                        dtcInfoPtr->DtcNvmDataPtr->EventId = DEM_EVENTID_INVAILD;
                        dtcInfoPtr->DtcNvmDataPtr->ExtendedDataAgingCounter = 0u;
                        dtcInfoPtr->DtcNvmDataPtr->DtcStatus = dtcInfoPtr->udsStatus;
                    }
                    NvM_WriteBlock(DemNvRamBlockIdMapTable[nvmIndex].DemNvRamBlockIdRef, (void*)(dtcInfoPtr->DtcNvmDataPtr));
                }
            }
            else
            {
                if(DemConf_NvmBlockId_Max > dtcInfoPtr->DtcNvmDataPtr->EventId)
                {
                    dtcInfoPtr = (Dem_DtcInfoType*)&Dem_DtcInfo[dtcInfoPtr->DtcNvmDataPtr->EventId];
                    dtcInfoPtr->udsStatus = dtcInfoPtr->DtcNvmDataPtr->DtcStatus;
                    dtcInfoPtr->udsStatus &= (~DEM_UDS_STATUS_TF);
                    dtcInfoPtr->udsStatus &= (~DEM_UDS_STATUS_TFTOC);
                }
            }
        }
    }
}

/*******************************************************************************
* -Name            Dem_GetOperationCycleState
* -Brief           Gets information about the status of a specific operation cycle.This API
                   can only be used through the RTE and therefore no declaration is exported via Dem.h.
* -Details         None
* -Param[in]       OperationCycleId:  Identification of operationcycle, like power cycle, driving cycle.
* -Param[out]      None
* -Return          E_OK: read out of operation cycle was successful
*                  E_NOT_OK: read out of operation cycle failed
*******************************************************************************/
Std_ReturnType Dem_GetOperationCycleState(
    uint8 OperationCycleId,
    Dem_OperationCycleStateType* CycleState
)
{

}

/*******************************************************************************
* -Name            Dem_Init
* -Brief           Initializes or reinitializes this module 
* -Details         None
* -Return          None          
*******************************************************************************/
void Dem_Init(
    const Dem_ConfigType* ConfigPtr
)
{
    uint8 nvmBlockId = DemConf_NvmBlockId_First;
    Dem_DtcNvmDataType* dtcNvmDataPtr;
    Dem_DtcInfoType* dtcInfoPtr;

    for(nvmBlockId = DemConf_NvmBlockId_First; nvmBlockId < DemConf_NvmBlockId_Max; nvmBlockId++)
    {
        dtcNvmDataPtr = (Dem_DtcNvmDataType*)(&Dem_DtcNvmData[nvmBlockId]);
        if(DemConf_NvmBlockId_Max > dtcNvmDataPtr->EventId)
        {
            dtcInfoPtr = (Dem_DtcInfoType*)&Dem_DtcInfo[dtcNvmDataPtr->EventId];
            dtcInfoPtr->DtcNvmDataPtr = dtcNvmDataPtr;
            dtcInfoPtr->udsStatus = dtcNvmDataPtr->DtcStatus;
            dtcInfoPtr->udsStatus &= (~DEM_UDS_STATUS_TF);
            dtcInfoPtr->udsStatus &= (~DEM_UDS_STATUS_TFTOC);
        }
    }
}


/*******************************************************************************
* -Name            Dem_MainFunction
* -Brief           Processes all not event based Dem internal functions
* -Details         None
* -Return          None
*******************************************************************************/
void Dem_MainFunction(
    void
)
{
    Dem_EventIdType eventId;
    Dem_DtcInfoType* dtcInfoPtr;
    Dem_EventParameterType* eventParameterConfigPtr;
    uint8 nvmIndex;

    for(eventId = 0u; eventId < DemConf_DemEventId_Max; eventId++)
    {
        dtcInfoPtr = (Dem_DtcInfoType*)&Dem_DtcInfo[eventId];
        eventParameterConfigPtr = (Dem_EventParameterType*)&Dem_EventParameterConfig[eventId];
        
        if(dtcInfoPtr->faultDetCounter <= DEM_CFG_COUNTER_PASSED_THRESHOLD(eventParameterConfigPtr))
        {
            if(DEM_UDS_STATUS_TF == (dtcInfoPtr->udsStatus & DEM_UDS_STATUS_TF))
            {
                dtcInfoPtr->udsStatus &= (~DEM_UDS_STATUS_TF);
            }
        }
        if(dtcInfoPtr->faultDetCounter >= DEM_CFG_COUNTER_FAILED_THRESHOLD(eventParameterConfigPtr))
        {
            if(DEM_UDS_STATUS_TF != (dtcInfoPtr->udsStatus & DEM_UDS_STATUS_TF))
            {
                dtcInfoPtr->udsStatus |= DEM_UDS_STATUS_TF;
                dtcInfoPtr->udsStatus |= DEM_UDS_STATUS_TFTOC;
                dtcInfoPtr->udsStatus |= DEM_UDS_STATUS_CDTC;
                Dem_LookupNvmIndex(eventId, &nvmIndex);
                dtcInfoPtr->DtcNvmDataPtr = (Dem_DtcNvmDataType*)&Dem_DtcNvmData[nvmIndex];
                
                dtcInfoPtr->DtcNvmDataPtr->EventId = eventId;
                dtcInfoPtr->DtcNvmDataPtr->DtcStatus = dtcInfoPtr->udsStatus;
                dtcInfoPtr->DtcNvmDataPtr->ExtendedDataAgingCounter = 0u;
                NvM_WriteBlock(DemNvRamBlockIdMapTable[nvmIndex].DemNvRamBlockIdRef, (void*)(dtcInfoPtr->DtcNvmDataPtr));
            }
        }
    }
}


